home *** CD-ROM | disk | FTP | other *** search
/ Hottest 6 / Hottest 6 (1996)(PDSoft)[!].iso / software / rendering / pov / povray40 / povray.c < prev    next >
C/C++ Source or Header  |  1978-11-24  |  27KB  |  858 lines

  1. /****************************************************************************
  2. *                povray.c
  3. *
  4. *  This module contains the entry routine for the raytracer and the code to
  5. *  parse the parameters on the command line.
  6. *
  7. *  from Persistence of Vision Raytracer
  8. *       Copyright 1992 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  Copying, distribution and legal info is in the file povlegal.doc which
  11. *  should be distributed with this file. If povlegal.doc is not available
  12. *  or for more info please contact:
  13. *
  14. *       Drew Wells [POV-Team Leader]
  15. *       CIS: 73767,1244  Internet: 73767.1244@compuserve.com
  16. *       Phone: (213) 254-4041
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23. #include <ctype.h>
  24. #include <time.h>          /* BP */
  25. #include "frame.h"              /* common to ALL modules in this program */
  26. #include "povproto.h"
  27.  
  28. #define MAX_FILE_NAMES 1
  29. unsigned int Options;
  30. int Quality;
  31. int Case_Sensitive_Flag = CASE_SENSITIVE_DEFAULT;
  32.  
  33. FILE *bfp;
  34.  
  35. extern FRAME Frame;
  36.  
  37. char Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH], Stat_File_Name[FILE_NAME_LENGTH];
  38.  
  39. #define MAX_LIBRARIES 10
  40. char *Library_Paths[MAX_LIBRARIES];
  41. int Library_Path_Index;
  42.  
  43. int Max_Symbols   = 500;
  44.  
  45. FILE_HANDLE *Output_File_Handle;
  46. int File_Buffer_Size;
  47. static int Number_Of_Files;
  48. static int inflag, outflag;
  49. DBL VTemp;
  50. DBL Antialias_Threshold;
  51. int First_Line, Last_Line;
  52. int Display_Started = FALSE;
  53. int Shadow_Test_Flag = FALSE;
  54.  
  55. /* Stats kept by the ray tracer: */
  56. long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  57. long Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded;
  58. long Ray_Box_Tests, Ray_Box_Tests_Succeeded;
  59. long Ray_Blob_Tests, Ray_Blob_Tests_Succeeded;
  60. long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
  61. long Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
  62. long Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
  63. long Ray_Poly_Tests, Ray_Poly_Tests_Succeeded;
  64. long Ray_Bicubic_Tests, Ray_Bicubic_Tests_Succeeded;
  65. long Ray_Ht_Field_Tests, Ray_Ht_Field_Tests_Succeeded;
  66. long Ray_Ht_Field_Box_Tests, Ray_HField_Box_Tests_Succeeded;
  67. long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  68. long Clipping_Region_Tests, Clipping_Region_Tests_Succeeded;
  69. long Calls_To_Noise, Calls_To_DNoise;
  70. long Shadow_Ray_Tests, Shadow_Rays_Succeeded;
  71. long Reflected_Rays_Traced, Refracted_Rays_Traced;
  72. long Transmitted_Rays_Traced;
  73. time_t tstart, tstop;
  74. DBL    tused;             /* Trace timer variables. - BP */
  75.  
  76. char DisplayFormat, OutputFormat, VerboseFormat, PaletteOption, Color_Bits;
  77.  
  78. extern SHORT RegUsed;
  79.  
  80.  
  81.  
  82.  
  83. #ifdef NOCMDLINE        /* a main() by any other name... */
  84. #ifdef ALTMAIN
  85. void alt_main()
  86. #else
  87. void main()
  88. #endif
  89. #else
  90. #ifdef ALTMAIN
  91. void alt_main(argc, argv)
  92. #else
  93. void main(argc, argv)
  94. #endif
  95. int argc;
  96. char **argv;
  97. #endif                  /* ...would be a lot less hassle!! :-) AAC */
  98. {
  99.    register int i;
  100.    FILE *stat_file;
  101.  
  102.    STARTUP_POVRAY
  103.  
  104.    PRINT_CREDITS
  105.  
  106.    PRINT_OTHER_CREDITS
  107.  
  108.    /* Parse the command line parameters */
  109. #ifndef NOCMDLINE
  110.    if (argc == 1)
  111.       usage();
  112. #endif
  113.  
  114.    init_vars();
  115.  
  116.    Output_File_Name[0]='\0';
  117.  
  118.    Library_Paths[0] = NULL;
  119.    Library_Path_Index = 0;
  120.  
  121.    /* Read the default parameters from povray.def */
  122.    get_defaults();
  123.  
  124. #ifndef NOCMDLINE
  125.    for (i = 1 ; i < argc ; i++ )
  126.       if ((*argv[i] == '+') || (*argv[i] == '-'))
  127.          parse_option(argv[i]);
  128.       else
  129.          parse_file_name(argv[i]);
  130. #endif
  131.  
  132.    if (Last_Line == -1)
  133.       Last_Line = Frame.Screen_Height;
  134.  
  135.    if (Options & DISKWRITE) {
  136.       switch (OutputFormat) {
  137.       case '\0':
  138.       case 'd':
  139.       case 'D':
  140.          if ((Output_File_Handle = Get_Dump_File_Handle()) == NULL) {
  141.             close_all();
  142.             exit(1);
  143.          }
  144.          break;
  145.          /*
  146.          case 'i':
  147.          case 'I':
  148.                    if ((Output_File_Handle = Get_Iff_File_Handle()) == NULL) {
  149.                       close_all();
  150.                       exit(1);
  151.                       }
  152.                    break;
  153.  
  154. */
  155.       case 'r':
  156.       case 'R':
  157.          if ((Output_File_Handle = Get_Raw_File_Handle()) == NULL) {
  158.             close_all();
  159.             exit(1);
  160.          }
  161.          break;
  162.  
  163.       case 't':
  164.       case 'T':
  165.          if ((Output_File_Handle = Get_Targa_File_Handle()) == NULL) {
  166.             close_all();
  167.             exit(1);
  168.          }
  169.          break;
  170.       default:
  171.          fprintf (stderr, "Unrecognized output file format %c\n", OutputFormat);
  172.          exit(1);
  173.       }
  174.       if (Output_File_Name[0] == '\0')
  175.          strcpy (Output_File_Name, Default_File_Name (Output_File_Handle));
  176.    }
  177.  
  178.    Print_Options();
  179.  
  180.    Initialize_Tokenizer(Input_File_Name);
  181.    fprintf (stderr,"Parsing...");
  182.    if (Options & VERBOSE_FILE){
  183.       stat_file = fopen(Stat_File_Name,"w+t");
  184.       fprintf (stat_file, "Parsing...\n");
  185.       fclose(stat_file);
  186.    }
  187.    Parse (&Frame);
  188.    Terminate_Tokenizer();
  189.    /* fprintf (stderr,"\n"); */
  190.  
  191.    if (Options & DISPLAY)
  192.    {
  193.       printf ("Displaying...\n");
  194.       display_init(Frame.Screen_Width, Frame.Screen_Height);
  195.       Display_Started = TRUE;
  196.    }
  197.  
  198.    /* Get things ready for ray tracing */
  199.    if (Options & DISKWRITE)
  200.       if (Options & CONTINUE_TRACE) {
  201.          if (Open_File (Output_File_Handle, Output_File_Name,
  202.             &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  203.             READ_MODE) != 1) {
  204.             fprintf (stderr, "Error opening continue trace output file\n");
  205.             fprintf (stderr, "Opening new output file %s.\n",Output_File_Name);
  206.             Options &= ~CONTINUE_TRACE; /* Turn off continue trace */
  207.  
  208.             if (Open_File (Output_File_Handle, Output_File_Name,
  209.                &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  210.                WRITE_MODE) != 1) {
  211.                fprintf (stderr, "Error opening output file\n");
  212.                close_all();
  213.                exit(1);
  214.             }
  215.          }
  216.  
  217.          Initialize_Renderer();
  218.          if (Options & CONTINUE_TRACE)
  219.             Read_Rendered_Part();
  220.       }
  221.       else {
  222.          if (Open_File (Output_File_Handle, Output_File_Name,
  223.             &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  224.             WRITE_MODE) != 1) {
  225.             fprintf (stderr, "Error opening output file\n");
  226.             close_all();
  227.             exit(1);
  228.          }
  229.  
  230.          Initialize_Renderer();
  231.       }
  232.    else
  233.       Initialize_Renderer();
  234.  
  235.    pq_init();
  236.    Initialize_Noise();
  237.  
  238.    START_TIME  /* Store start time for trace. Timer macro in CONFIG.H */
  239.  
  240.    /* Ok, go for it - trace the picture */
  241.    if ((Options & VERBOSE) && (VerboseFormat !='1'))
  242.       printf ("Rendering...\n");
  243.    else if ((Options & VERBOSE) && (VerboseFormat=='1'))
  244.       fprintf (stderr,"POV-Ray rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  245.    if (Options & VERBOSE_FILE){
  246.       stat_file = fopen(Stat_File_Name,"w+t");
  247.       fprintf (stat_file,"Parsed ok. Now rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  248.       fclose(stat_file);
  249.    }
  250.  
  251.    CONFIG_MATH               /* Macro for setting up any special FP options */
  252.    Start_Tracing ();
  253.  
  254.    if (Options & VERBOSE && VerboseFormat=='1')
  255.       fprintf (stderr,"\n");
  256.  
  257.    /* Record the time so well spent... */
  258.    STOP_TIME                  /* Get trace done time. */
  259.    tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  260.    /* 0 in your specific CONFIG.H if unsupported */
  261.  
  262.    /* Clean up and leave */
  263.    display_finished();
  264.  
  265.    close_all ();
  266.  
  267.    PRINT_STATS
  268.  
  269.    if (Options & VERBOSE_FILE){
  270.       stat_file = fopen(Stat_File_Name,"a+t");
  271.       fprintf (stat_file,"Done Tracing\n");
  272.       fclose(stat_file);
  273.    }
  274.  
  275.    FINISH_POVRAY
  276. }
  277.  
  278. /* Print out usage error message */
  279.  
  280. void usage ()
  281. {
  282.    WAIT_FOR_KEYPRESS
  283.    fprintf (stdout,"\nUsage:");
  284.    fprintf (stdout,"\n   povray  [+/-] Option1 [+/-] Option2 ...");
  285.    fprintf (stdout,"\n");
  286.    fprintf (stdout,"\n Options: ");
  287.    fprintf (stdout,"\n    dxy = display in format x, using palette option y");
  288.    fprintf (stdout,"\n    vx  = verbose in format x");
  289.    /*fprintf (stdout,"\n    @filename  = verbose to file name -- see docs");*/
  290.    fprintf (stdout,"\n    p  = pause before exit");
  291.    fprintf (stdout,"\n    x  = enable early exit by key hit");
  292.    fprintf (stdout,"\n    fx = write output file in format x");
  293.    fprintf (stdout,"\n         ft - Uncompressed Targa-24  fd - DKB/QRT Dump  fr - 3 Raw Files");
  294.    fprintf (stdout,"\n    a  = perform antialiasing");
  295.    fprintf (stdout,"\n    c  = continue aborted trace");
  296.    fprintf (stdout,"\n    qx = image quality 0=rough, 9=full");
  297.    fprintf (stdout,"\n    l<pathname> = library path prefix");
  298.    fprintf (stdout,"\n    wxxx = width of the screen");
  299.    fprintf (stdout,"\n    hxxx = height of the screen");
  300.    fprintf (stdout,"\n    sxxx = start at line number xxx");
  301.    fprintf (stdout,"\n    exxx = end at line number xxx");
  302.    fprintf (stdout,"\n    bxxx = Use xxx kilobytes for output file buffer space");
  303.    fprintf (stdout,"\n    i<filename> = input file name");
  304.    fprintf (stdout,"\n    o<filename> = output file name");
  305.    fprintf (stdout,"\n  Ex: +l\\povray\\include +iscene.pov +oscene.tga +w320 +h200 +d -v +x");
  306.    fprintf (stdout,"\n  Ex: +iscene.pov +oscene.tga +w160 +h200 +v -d +x");
  307.    fprintf (stdout,"\n");
  308.    exit(1);
  309. }
  310.  
  311. void init_vars()
  312. {
  313.    Output_File_Handle = NULL;
  314.    File_Buffer_Size = 0;
  315.    Options = 0;
  316.    Quality = 9;
  317.    Number_Of_Files = 0;
  318.    First_Line = 0;
  319.    Last_Line = -1;
  320.    Color_Bits = 8;
  321.  
  322.    Number_Of_Pixels = 0L;
  323.    Number_Of_Rays = 0L;
  324.    Number_Of_Pixels_Supersampled = 0L;
  325.    Ray_Ht_Field_Tests = 0L;
  326.    Ray_Ht_Field_Tests_Succeeded = 0L;
  327.    Ray_Ht_Field_Box_Tests = 0L;
  328.    Ray_HField_Box_Tests_Succeeded = 0L;
  329.    Ray_Bicubic_Tests = 0L;
  330.    Ray_Bicubic_Tests_Succeeded = 0L;
  331.    Ray_Blob_Tests = 0L;
  332.    Ray_Blob_Tests_Succeeded = 0L;
  333.    Ray_Box_Tests = 0L;
  334.    Ray_Box_Tests_Succeeded = 0L;
  335.    Ray_Sphere_Tests = 0L;
  336.    Ray_Sphere_Tests_Succeeded = 0L;
  337.    Ray_Plane_Tests = 0L;
  338.    Ray_Plane_Tests_Succeeded = 0L;
  339.    Ray_Triangle_Tests = 0L;
  340.    Ray_Triangle_Tests_Succeeded = 0L;
  341.    Ray_Quadric_Tests = 0L;
  342.    Ray_Quadric_Tests_Succeeded = 0L;
  343.    Ray_Poly_Tests = 0L;
  344.    Ray_Poly_Tests_Succeeded = 0L;
  345.    Bounding_Region_Tests = 0L;
  346.    Bounding_Region_Tests_Succeeded = 0L;
  347.    Clipping_Region_Tests = 0L;
  348.    Clipping_Region_Tests_Succeeded = 0L;
  349.    Calls_To_Noise = 0L;
  350.    Calls_To_DNoise = 0L;
  351.    Shadow_Ray_Tests = 0L;
  352.    Shadow_Rays_Succeeded = 0L;
  353.    Reflected_Rays_Traced = 0L;
  354.    Refracted_Rays_Traced = 0L;
  355.    Transmitted_Rays_Traced = 0L;
  356.  
  357.    Frame.Screen_Height = 100;
  358.    Frame.Screen_Width = 100;
  359.  
  360.    Antialias_Threshold = 0.3;
  361.    strcpy (Input_File_Name, "object.dat");
  362.    return;
  363. }
  364.  
  365. /* Close all the stuff that has been opened. */
  366. void close_all ()
  367. {
  368.    if ((Options & DISPLAY) && Display_Started)
  369.       display_close();
  370.  
  371.    if (Output_File_Handle)
  372.       Close_File (Output_File_Handle);
  373. }
  374.  
  375. /* Read the default parameters from povray.def */
  376. void get_defaults()
  377. {
  378.    FILE *defaults_file;
  379.    char Option_String[256], *Option_String_Ptr;
  380.    /* READ_ENV_VAR_? should be defined in config.h */
  381.    /* Only one READ_ENV_VAR_? should ever be defined. */
  382.    /* This allows some machines to read environment variable before */
  383.    /* reading povray.def and others to do it after depending on the */
  384.    /* operating system. IBM-PC is before. Default is after if not */
  385.    /* defined in config.h. CDW 2/92 */
  386.    /* Set Diskwrite as default */
  387.    Options |= DISKWRITE;
  388.    OutputFormat = DEFAULT_OUTPUT_FORMAT;
  389.  
  390.    READ_ENV_VAR_BEFORE
  391.    if ((defaults_file = Locate_File("povray.def", "r")) != NULL) {
  392.       while (fgets(Option_String, 256, defaults_file) != NULL)
  393.          read_options(Option_String);
  394.       fclose (defaults_file);
  395.    }
  396.    READ_ENV_VAR_AFTER
  397. }
  398.  
  399. void read_options (Option_Line)
  400. char *Option_Line;
  401. {
  402.    register int c, String_Index, Option_Started;
  403.    short Option_Line_Index = 0;
  404.    char Option_String[80];
  405.  
  406.    String_Index = 0;
  407.    Option_Started = FALSE;
  408.    while ((c = Option_Line[Option_Line_Index++]) != '\0')
  409.    {
  410.       if (Option_Started)
  411.          if (isspace(c))
  412.          {
  413.             Option_String[String_Index] = '\0';
  414.             parse_option (Option_String);
  415.             Option_Started = FALSE;
  416.             String_Index = 0;
  417.          }
  418.          else
  419.             Option_String[String_Index++] = (char) c;
  420.  
  421.       else /* Option_Started */
  422.          if ((c == (int) '-') || (c == (int) '+'))
  423.          {
  424.             String_Index = 0;
  425.             Option_String[String_Index++] = (char) c;
  426.             Option_Started = TRUE;
  427.          }
  428.          else
  429.             if (!isspace(c))
  430.             {
  431.                fprintf (stderr, "\nBad default file format.  Offending char: (%c), val: %d.\n", (char) c, c);
  432.                exit (1);
  433.             }
  434.    }
  435.  
  436.    if (Option_Started)
  437.    {
  438.       Option_String[String_Index] = '\0';
  439.       parse_option (Option_String);
  440.    }
  441. }
  442.  
  443. /* parse the command line parameters */
  444. void parse_option (Option_String)
  445. char *Option_String;
  446. {
  447.    register int Add_Option;
  448.    unsigned int Option_Number;
  449.    DBL threshold;
  450.  
  451.    inflag = outflag = FALSE;   /* if these flags aren't immediately used, reset them on next -/+ option! */
  452.    if (*(Option_String++) == '-')
  453.       Add_Option = FALSE;
  454.    else
  455.       Add_Option = TRUE;
  456.  
  457.    switch (*Option_String)
  458.    {
  459.    case 'B':
  460.    case 'b':
  461.       sscanf (&Option_String[1], "%d", &File_Buffer_Size);
  462.       File_Buffer_Size *= 1024;
  463.       if (File_Buffer_Size < BUFSIZ)
  464.          File_Buffer_Size = BUFSIZ;
  465.       Option_Number = 0;
  466.       break;
  467.  
  468.    case 'C':
  469.    case 'c':
  470.       Option_Number = CONTINUE_TRACE;
  471.       break;
  472.  
  473.    case 'D':
  474.    case 'd':
  475.       Option_Number = DISPLAY;
  476.       DisplayFormat = '0';
  477.       PaletteOption = '3';
  478.       if (Option_String[1] != '\0')
  479.          DisplayFormat = (char)toupper(Option_String[1]);
  480.  
  481.       if (Option_String[1] != '\0' && Option_String[2] != '\0')
  482.          PaletteOption = (char)toupper(Option_String[2]);
  483.       break;
  484.  
  485.    case '@':
  486.       Option_Number = VERBOSE_FILE;
  487.       if(Option_String[1] == '\0')
  488.          strcpy(Stat_File_Name, "POVSTAT.OUT");
  489.       else
  490.          strncpy (Stat_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  491.       break;
  492.    case 'V':
  493.    case 'v':
  494.       Option_Number = VERBOSE;
  495.       VerboseFormat = (char)toupper(Option_String[1]);
  496.       if (VerboseFormat == '\0')
  497.          VerboseFormat = '1';
  498.       break;
  499.  
  500.    case 'W':
  501.    case 'w':
  502.       sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
  503.       Option_Number = 0;
  504.       break;
  505.  
  506.    case 'H':
  507.    case 'h':
  508.       sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
  509.       Option_Number = 0;
  510.       break;
  511.  
  512.    case 'F':
  513.    case 'f':
  514.       Option_Number = DISKWRITE;
  515.       if (isupper(Option_String[1]))
  516.          OutputFormat = (char)tolower(Option_String[1]);
  517.       else
  518.          OutputFormat = Option_String[1];
  519.  
  520.       /* Default the output format to the default in the config file */
  521.       if (OutputFormat == '\0')
  522.          OutputFormat = DEFAULT_OUTPUT_FORMAT;
  523.       break;
  524.  
  525.    case 'P':
  526.    case 'p':
  527.       Option_Number = PROMPTEXIT;
  528.       break;
  529.  
  530.    case 'I':
  531.    case 'i':
  532.       if (Option_String[1] == '\0')
  533.          inflag = TRUE;
  534.       else
  535.          strncpy (Input_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  536.       Option_Number = 0;
  537.       break;
  538.  
  539.    case 'O':
  540.    case 'o':
  541.       if (Option_String[1] == '\0')
  542.          outflag = TRUE;
  543.       else
  544.          strncpy (Output_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  545.       Option_Number = 0;
  546.       break;
  547.  
  548.    case 'A':
  549.    case 'a':
  550.       Option_Number = ANTIALIAS;
  551.       if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
  552.          Antialias_Threshold = threshold;
  553.       break;
  554.  
  555.    case 'X':
  556.    case 'x':
  557.       Option_Number = EXITENABLE;
  558.       break;
  559.  
  560.  
  561.    case 'L':
  562.    case 'l':
  563.       if (Library_Path_Index >= MAX_LIBRARIES) {
  564.          fprintf (stderr, "Too many library directories specified\n");
  565.          exit(1);
  566.       }
  567.       Library_Paths [Library_Path_Index] = malloc (strlen(Option_String));
  568.       if (Library_Paths [Library_Path_Index] == NULL) {
  569.          fprintf (stderr, "Out of memory. Cannot allocate memory for library pathname\n");
  570.          exit(1);
  571.       }
  572.       strcpy (Library_Paths [Library_Path_Index], &Option_String[1]);
  573.       Library_Path_Index++;
  574.       Option_Number = 0;
  575.       break;
  576.    case 'T':
  577.    case 't':
  578.       switch (toupper(Option_String[1])){
  579.       case 'Y':
  580.          Case_Sensitive_Flag = 0;
  581.          break;
  582.       case 'N':
  583.          Case_Sensitive_Flag = 1;
  584.          break;
  585.       case 'O':
  586.          Case_Sensitive_Flag = 2;
  587.          break;
  588.       default:
  589.          Case_Sensitive_Flag = 2;
  590.          break;
  591.       }
  592.       Option_Number = 0;
  593.       break;
  594.  
  595.    case 'S':
  596.    case 's':
  597.       sscanf (&Option_String[1], "%d", &First_Line);
  598.       Option_Number = 0;
  599.       break;
  600.  
  601.    case 'E':
  602.    case 'e':
  603.       sscanf (&Option_String[1], "%d", &Last_Line);
  604.       Option_Number = 0;
  605.       break;
  606.  
  607.    case 'M': /* Switch used so other max values can be inserted easily */
  608.    case 'm':
  609.       switch (Option_String[1]){
  610.       case 's': /* Max Symbols */
  611.       case 'S':
  612.          sscanf (&Option_String[2], "%d", &Max_Symbols);
  613.          Option_Number = 0;
  614.          break;
  615.       default:
  616.          break;
  617.       }
  618.       break;
  619.  
  620.    case 'Q':
  621.    case 'q':
  622.       sscanf (&Option_String[1], "%d", &Quality);
  623.       Option_Number = 0;
  624.       break;
  625.  
  626.       /* Turn on debugging print statements. */
  627.    case 'Z':
  628.    case 'z':
  629.       Option_Number = DEBUGGING;
  630.       break;
  631.  
  632.    default:
  633.       fprintf (stderr, "\nInvalid option: %s\n\n", --Option_String);
  634.       Option_Number = 0;
  635.    }
  636.  
  637.    if (Option_Number != 0)
  638.       if (Add_Option)
  639.          Options |= Option_Number;
  640.       else Options &= ~Option_Number;
  641. }
  642.  
  643.    void Print_Options()
  644.    {
  645.       int i;
  646.  
  647.       fprintf (stdout,"\nPOV-Ray    Options in effect: ");
  648.  
  649.       if (Options & CONTINUE_TRACE)
  650.          fprintf (stdout,"+c ");
  651.  
  652.       if (Options & DISPLAY)
  653.          fprintf (stdout,"+d%c%c ", DisplayFormat, PaletteOption);
  654.  
  655.       if (Options & VERBOSE)
  656.          fprintf (stdout,"+v%c ", VerboseFormat);
  657.  
  658.       if (Options & VERBOSE_FILE)
  659.          fprintf (stdout,"+@%s ", Stat_File_Name);
  660.  
  661.       if (Options & DISKWRITE)
  662.          fprintf (stdout,"+f%c ", OutputFormat);
  663.  
  664.       if (Options & PROMPTEXIT)
  665.          fprintf (stdout,"+p ");
  666.  
  667.       if (Options & EXITENABLE)
  668.          fprintf (stdout,"+x ");
  669.  
  670.       if (Options & ANTIALIAS)
  671.          fprintf (stdout,"+a%f ", Antialias_Threshold);
  672.  
  673.       if (Options & DEBUGGING)
  674.          fprintf (stdout,"+z ");
  675.  
  676.       if (File_Buffer_Size != 0)
  677.          fprintf (stdout,"-b%d ", File_Buffer_Size/1024);
  678.  
  679.       fprintf (stdout,"-q%d -w%d -h%d -s%d -e%d\n-i%s ",
  680.          Quality, Frame.Screen_Width, Frame.Screen_Height,
  681.          First_Line, Last_Line, Input_File_Name);
  682.  
  683.       if (Options & DISKWRITE)
  684.          fprintf (stdout,"-o%s ", Output_File_Name);
  685.  
  686.       for (i = 0 ; i < Library_Path_Index ; i++)
  687.          fprintf (stdout,"-l%s ", Library_Paths[i]);
  688.  
  689.       fprintf (stdout,"\n");
  690.    }
  691.  
  692. void parse_file_name (File_Name)
  693. char *File_Name;
  694. {
  695.    FILE *defaults_file;
  696.    char Option_String[256];
  697.  
  698.    if (inflag)   /* file names may now be separated by spaces from cmdline option */
  699.    {
  700.       strncpy (Input_File_Name, File_Name, FILE_NAME_LENGTH);
  701.       inflag = FALSE;
  702.       return;
  703.    }
  704.  
  705.    if (outflag)  /* file names may now be separated by spaces from cmdline option */
  706.    {
  707.       strncpy (Output_File_Name, File_Name, FILE_NAME_LENGTH);
  708.       outflag = FALSE;
  709.       return;
  710.    }
  711.  
  712.  
  713.    if (++Number_Of_Files > MAX_FILE_NAMES)
  714.    {
  715.       fprintf (stderr, "\nOnly %d option file names are allowed in a command line.",
  716.          MAX_FILE_NAMES);
  717.       exit(1);
  718.    }
  719.  
  720.    if ((defaults_file = Locate_File(File_Name, "r")) != NULL) {
  721.       while (fgets(Option_String, 256, defaults_file) != NULL)
  722.          read_options(Option_String);
  723.       fclose (defaults_file);
  724.    }
  725.    else
  726.       printf("\nError opening option file %s.",File_Name);
  727. }
  728.  
  729. void print_stats()
  730. {
  731.    int hours,min;
  732.    DBL sec;
  733.    FILE *stat_out;
  734.    long Pixels_In_Image;
  735.  
  736.    if (Options & VERBOSE_FILE)
  737.       stat_out = fopen(Stat_File_Name,"w+t");
  738.    else
  739.       stat_out = stdout;
  740.  
  741.    Pixels_In_Image = (long)Frame.Screen_Width * (long)Frame.Screen_Height;
  742.  
  743.  
  744.    fprintf (stat_out,"\n%s statistics\n",Input_File_Name);
  745.    if(Pixels_In_Image > Number_Of_Pixels)
  746.       fprintf (stat_out,"  Partial Image Rendered\n");
  747.  
  748.    fprintf (stat_out,"--------------------------------------\n");
  749.    fprintf (stat_out,"Resolution %d x %d\n",Frame.Screen_Width, Frame.Screen_Height);
  750.    fprintf (stat_out,"# Rays:  %10ld    # Pixels:  %10ld  # Pixels supersampled: %10ld\n",
  751.       Number_Of_Rays, Number_Of_Pixels, Number_Of_Pixels_Supersampled);
  752.  
  753.    fprintf (stat_out,"  Ray->Shape Intersection Tests:\n");
  754.    fprintf (stat_out,"   Type             Tests    Succeeded   Percentage\n");
  755.    fprintf (stat_out,"  -----------------------------------------------------------\n");
  756.    if(Ray_Sphere_Tests)
  757.       fprintf (stat_out,"  Sphere       %10ld  %10ld  %10.2f\n", Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded, ( ((DBL)Ray_Sphere_Tests_Succeeded/(DBL)Ray_Sphere_Tests) *100.0 ) );
  758.    if(Ray_Plane_Tests)
  759.       fprintf (stat_out,"  Plane        %10ld  %10ld  %10.2f\n", Ray_Plane_Tests, Ray_Plane_Tests_Succeeded, ( ((DBL)Ray_Plane_Tests_Succeeded/(DBL)Ray_Plane_Tests) *100.0 ));
  760.    if(Ray_Triangle_Tests)
  761.       fprintf (stat_out,"  Triangle     %10ld  %10ld  %10.2f\n", Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded, ( ((DBL)Ray_Triangle_Tests_Succeeded/(DBL)Ray_Triangle_Tests) *100.0 ));
  762.    if(Ray_Quadric_Tests)
  763.       fprintf (stat_out,"  Quadric      %10ld  %10ld  %10.2f\n", Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded, ( ((DBL)Ray_Quadric_Tests_Succeeded/(DBL)Ray_Quadric_Tests) *100.0 ));
  764.    if(Ray_Blob_Tests)
  765.       fprintf (stat_out,"  Blob         %10ld  %10ld  %10.2f\n", Ray_Blob_Tests, Ray_Blob_Tests_Succeeded, ( ((DBL)Ray_Blob_Tests_Succeeded/(DBL)Ray_Blob_Tests) *100.0 ));
  766.    if(Ray_Box_Tests)
  767.       fprintf (stat_out,"  Box          %10ld  %10ld  %10.2f\n", Ray_Box_Tests, Ray_Box_Tests_Succeeded, ( ((DBL)Ray_Box_Tests_Succeeded/(DBL)Ray_Box_Tests) *100.0 ));
  768.    if(Ray_Poly_Tests)
  769.       fprintf (stat_out,"  Quartic\\Poly %10ld  %10ld  %10.2f\n", Ray_Poly_Tests, Ray_Poly_Tests_Succeeded, ( ((DBL)Ray_Poly_Tests_Succeeded/(DBL)Ray_Poly_Tests) *100.0 ));
  770.    if(Ray_Bicubic_Tests)
  771.       fprintf (stat_out,"  Bezier Patch %10ld  %10ld  %10.2f\n", Ray_Bicubic_Tests, Ray_Bicubic_Tests_Succeeded, ( ((DBL)Ray_Bicubic_Tests_Succeeded/(DBL)Ray_Bicubic_Tests) *100.0 ));
  772.    if(Ray_Ht_Field_Tests)
  773.       fprintf (stat_out,"  Height Fld   %10ld  %10ld  %10.2f\n", Ray_Ht_Field_Tests, Ray_Ht_Field_Tests_Succeeded, ( ((DBL)Ray_Ht_Field_Tests_Succeeded/(DBL)Ray_Ht_Field_Tests) *100.0 ));
  774.    if(Ray_Ht_Field_Box_Tests)
  775.       fprintf (stat_out,"  Hght Fld Box %10ld  %10ld  %10.2f\n", Ray_Ht_Field_Box_Tests, Ray_HField_Box_Tests_Succeeded, ( ((DBL)Ray_HField_Box_Tests_Succeeded/(DBL)Ray_Ht_Field_Box_Tests) *100.0 ));
  776.    if(Bounding_Region_Tests)
  777.       fprintf (stat_out,"  Bounds       %10ld  %10ld  %10.2f\n", Bounding_Region_Tests, Bounding_Region_Tests_Succeeded, ( ((DBL)Bounding_Region_Tests_Succeeded/(DBL)Bounding_Region_Tests) *100.0 ));
  778.    if(Clipping_Region_Tests)
  779.       fprintf (stat_out,"  Clips        %10ld  %10ld  %10.2f\n", Clipping_Region_Tests, Clipping_Region_Tests_Succeeded, ( ((DBL)Clipping_Region_Tests_Succeeded/(DBL)Clipping_Region_Tests) *100.0 ));
  780.  
  781.    if(Calls_To_Noise)
  782.  
  783.       fprintf (stat_out,"  Calls to Noise:   %10ld\n", Calls_To_Noise);
  784.    if(Calls_To_DNoise)
  785.       fprintf (stat_out,"  Calls to DNoise:  %10ld\n", Calls_To_DNoise);
  786.    if(Shadow_Ray_Tests)
  787.       fprintf (stat_out,"  Shadow Ray Tests: %10ld     Blocking Objects Found:  %10ld\n",
  788.          Shadow_Ray_Tests, Shadow_Rays_Succeeded);
  789.    if(Reflected_Rays_Traced)
  790.       fprintf (stat_out,"  Reflected Rays:   %10ld\n", Reflected_Rays_Traced);
  791.    if(Refracted_Rays_Traced)
  792.       fprintf (stat_out,"  Refracted Rays:   %10ld\n", Refracted_Rays_Traced);
  793.    if(Transmitted_Rays_Traced)
  794.       fprintf (stat_out,"  Transmitted Rays: %10ld\n", Transmitted_Rays_Traced);
  795.  
  796.    if(tused==0) {
  797.       STOP_TIME                  /* Get trace done time. */
  798.       tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  799.       /* 0 in your specific CONFIG.H if unsupported */
  800.    }
  801.    if (tused != 0){
  802.       /* Convert seconds to hours, min & sec. CdW */
  803.       hours = (int) tused/3600;
  804.       min = (int) (tused - hours*3600)/60;
  805.       sec = tused - (DBL) (hours*3600 + min*60);
  806.       fprintf (stat_out,"  Time For Trace:   %2d hours %2d minutes %4.2f seconds\n", hours,min,sec);
  807.    }
  808.  
  809.    if (DisplayFormat == '8')
  810.       fprintf (stat_out,"  HAM8 ColourRegisters used:  %d\n",RegUsed);
  811.  
  812.    if (Options & VERBOSE_FILE)
  813.       fclose(stat_out);
  814.  
  815. }
  816.  
  817. /* Find a file in the search path. */
  818.  
  819. FILE *Locate_File (filename, mode)
  820. char *filename, *mode;
  821. {
  822.    FILE *f;
  823.    int i;
  824.    char pathname[FILE_NAME_LENGTH];
  825.  
  826.    /* Check the current directory first. */
  827.    if ((f = fopen (filename, mode)) != NULL)
  828.       return (f);
  829.  
  830.    for (i = 0 ; i < Library_Path_Index ; i++) {
  831.       strcpy (pathname, Library_Paths[i]);
  832.       if (FILENAME_SEPARATOR != NULL)
  833.          strcat (pathname, FILENAME_SEPARATOR);
  834.       strcat (pathname, filename);
  835.       if ((f = fopen (pathname, mode)) != NULL)
  836.          return (f);
  837.    }
  838.  
  839.    return (NULL);
  840. }
  841. void print_credits()
  842. {
  843.    fprintf (stderr,"\n");
  844.    fprintf (stderr,"  Persistence of Vision Raytracer Ver 1.0%s\n",COMPILER_VER);
  845.    fprintf (stderr,"  Copyright 1992 POV-Team\n");
  846.    fprintf (stderr,"  ----------------------------------------------------------------------\n");
  847.    fprintf (stderr,"  POV-Ray is based on DKBTrace 2.12 by David K. Buck & Aaron A. Collins.\n");
  848.    fprintf (stderr,"  \n");
  849.    fprintf (stderr,"  Contributing Authors: (Alphabetically)\n");
  850.    fprintf (stderr,"  \n");
  851.    fprintf (stderr,"  Steve A. Bennett   David K. Buck      Aaron A. Collins\n");
  852.    fprintf (stderr,"  Alexander Enzmann  Dan Farmer         Girish T. Hagan\n");
  853.    fprintf (stderr,"  Douglas Muir       Bill Pulver        Robert Skinner\n");
  854.    fprintf (stderr,"  Scott Taylor       Drew Wells         Chris Young\n");
  855.    fprintf (stderr,"  ----------------------------------------------------------------------\n");
  856.    fprintf (stderr,"  Other contributors listed in the documentation.\n");
  857. }
  858.